package edu.uj.petri.common;

import edu.uj.petri.model.ObjectModelFactory;
import edu.uj.petri.simulation.StandardSimulation;
import edu.uj.util.AbstractSettings;
import edu.uj.util.XMLSettingsSource;
import edu.uj.petri.model.ModelFactory;
import edu.uj.petri.simulation.Simulation;
import javax.swing.UIManager;

/**
 * stores program settings.
 * @author Piotrek
 */
public class Settings extends AbstractSettings {
    
    enum LnF {CROSS_PLATFORM, GTK, METAL, MOTIF, NATIVE, WINDOWS, WINDOWS_CLASSIC};
    
    private static Settings instance=null;
    
    private ModelFactory mfInstance;
    
    private LnF lookAndFeel=LnF.NATIVE;
    
    private boolean useAntialiasing=true;
    
    protected Settings() {
        super(new XMLSaver());
        mfInstance = new ObjectModelFactory();
    }
    
    public static Settings getInstance() {
        if (instance == null)
            instance = new Settings();
        return instance;
    }
    
    public String getLookAndFeelName() {
        switch(lookAndFeel) {
            case CROSS_PLATFORM:
                return UIManager.getCrossPlatformLookAndFeelClassName();
            case GTK:
                return "com.sun.java.swing.plaf.gtk.GTKLookAndFeel";
            case METAL:
                return "javax.swing.plaf.metal.MetalLookAndFeel";
            case MOTIF:
                return "com.sun.java.swing.plaf.motif.MotifLookAndFeel";
            case WINDOWS:
                return "com.sun.java.swing.plaf.windows.WindowsLookAndFeel";
            case WINDOWS_CLASSIC:
                return "com.sun.java.swing.plaf.windows.WindowsClassicLookAndFeel";
            default: // native
                return UIManager.getSystemLookAndFeelClassName();
        }
    }

    public ModelFactory getModelFactory() {
        return this.mfInstance;
    }
    
    
    public boolean getUseAntialiasing() {
        return useAntialiasing;
    }

    public void setUseAntialiasing(boolean useAntialiasing) {
        this.useAntialiasing = useAntialiasing;
    }
    
    public Simulation createSimulation() {
        return new StandardSimulation();
    }
    
    
    void setLookAndFeel(LnF lnf) {
        lookAndFeel = lnf;
    }
    
    LnF getLookAndFeel() {
        return lookAndFeel;
    }
    
    
    
    /**
     * saves settings to XML file
     */
    static class XMLSaver extends XMLSettingsSource {
        XMLSaver() {
            super("petrisimulator", "simulator.xml");
        }
        
        protected void handleKey(String key, String value, AbstractSettings settings) throws Exception {
            Settings s = (Settings)settings;
            if (key.equals("lookAndFeel"))
                s.setLookAndFeel(stringToLnF(value));
            else if (key.equals("useAntialiasing"))
                s.setUseAntialiasing(readBoolean(value));
            else // DEBUG ONLY
                System.err.printf("unknown key: %s with value %s\n", key);
        }
        
        protected void prepareToSave(AbstractSettings settings) {
            Settings s = (Settings)settings;
            saveValue("lookAndFeel", lnfToString(s.getLookAndFeel()));
            saveValue("useAntialiasing", s.getUseAntialiasing());
        }
        
        private String lnfToString(LnF lnf) {
            switch(lnf) {
                case CROSS_PLATFORM:
                    return "cross-platform";
                case GTK:
                    return "gtk";
                case METAL:
                    return "metal";
                case MOTIF:
                    return "motif";
                case WINDOWS:
                    return "windows";
                case WINDOWS_CLASSIC:
                    return "windows classic";
                default:
                    return "native";
            }
        }
        
        private LnF stringToLnF(String string) {
            if (string.equals("cross-platform"))
                return LnF.CROSS_PLATFORM;
            if (string.equals("gtk"))
                return LnF.GTK;
            else if (string.equals("metal"))
                return LnF.METAL;
            else if (string.equals("motif"))
                return LnF.MOTIF;
            else if (string.equals("windows"))
                return LnF.WINDOWS;
            else if (string.equals("windows classic"))
                return LnF.WINDOWS_CLASSIC;
            else
                return LnF.NATIVE;
        }
        
    }

}
